﻿using System;
using System.IO;
using System.Net.Mail;
using System.Net.Sockets;
using System.Text;
using System.Threading;


namespace MotivLogger
{
    
    public class TcpCommunicationTB : BaseCommunication 
    {

        private TcpListener listen;
        private Thread serverthread;
        private static bool serverinited = false;
        private Socket s = null;
        

        public override void CreateServer() 
        {
            if (!serverinited)
            {
                int port = 12321;
                if(Settings.getSetting("fpf_routine_manager")!=null)
                    port = Settings.getSetting("fpf_routine_manager").GetInt("serverport", 12321);
                listen = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), port);
                serverthread = new Thread(DoListen);
                serverthread.Start();
                serverinited=true;
            }
        }

        private void DoListen()
        {
            listen.Start();
            
            while (serverinited)
            {
                try
                {
                    TcpClient client = listen.AcceptTcpClient();
                    Thread clientThread = new Thread(DoClient) { IsBackground = true };
                    clientThread.Start(client);
                }
                catch { }
            }
        }

        private void DoClient(object client)
        {
            TcpClient tClient = (TcpClient)client;
            while (serverinited)
            {
                if (!tClient.Connected)
                {
                    tClient.Close();
                    Thread.CurrentThread.Abort();
                }

                if (tClient.Available > 0)
                {
                    Socket s = tClient.Client;
                    byte[] header = new byte[50];
                    byte[] buffer= new byte[2048];
                    s.Receive(header, 50, SocketFlags.None);
                    var messagesize = Encoding.UTF8.GetString(header).Replace("%message headers%","").Replace("length:","").Trim(' ');
                    int size = 0;
                    Int32.TryParse(messagesize, out size);
                    s.Receive(buffer,size,SocketFlags.None);
                    var request = Encoding.UTF8.GetString(buffer);
                    NewMessage(request.Trim('\0'));
                }
                Thread.Sleep(200);
            }
        }

        public void Connect()
        {
            try 
            {
                int port = Settings.getSetting("fpf_routine_manager").GetInt("serverport", 12321);
                TcpClient tcpClient = new TcpClient("127.0.0.1", port);
                s = tcpClient.Client;
            }
            catch { }
        }

        public override void Send(string message) 
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("%message headers% length: {0:D5} %message headers% ", message.Length);
            sb.Append(message);
            byte[] msg = Encoding.UTF8.GetBytes(sb.ToString());
            try
            {
                if (s == null)
                    Connect();
                if(serverinited)
                    Send(s, msg, 0, msg.Length, 1000);
            }
            catch
            {
                Thread.Sleep(100);
                Connect();
                if (serverinited)
                    Send(s, msg, 0, msg.Length, 1000);
            }
        }
  
        private void Send(Socket socket, byte[] buffer, int offset, int size, int timeout)
        {
            int startTickCount = Environment.TickCount;
            int sent = 0;  // how many bytes is already sent
            do
            {
                if (Environment.TickCount > startTickCount + timeout)
                    throw new Exception("Timeout.");
                try
                {
                    sent += socket.Send(buffer, offset + sent, size - sent, SocketFlags.None);
                }
                catch (SocketException ex)
                {
                    if (ex.SocketErrorCode == SocketError.WouldBlock ||
                        ex.SocketErrorCode == SocketError.IOPending ||
                        ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                    {
                        // socket buffer is probably full, wait and try again
                        Thread.Sleep(30);
                    }
                    else
                        throw ex;  // any serious error occurr
                }
            } while (sent < size);
        }

        public override void Stop()
        {
            s.Close();
        }

        public override void ServerStop()
        {
            serverinited = false;
            listen.Stop();
            serverthread.Abort();
        }
        
        public static void MailSend(string body)
        {

            MailMessage Message = new MailMessage();
            SmtpClient Smtp = new SmtpClient("smtp.yandex.ru", 25);


            Message.Subject = "Тема";
            Message.Body = body;
            Message.From = new System.Net.Mail.MailAddress("fileprocessing@yandex.ru");
            Message.To.Add(new MailAddress("toricray@gmail.com"));

            Smtp.EnableSsl = true; 
            Smtp.Credentials = new System.Net.NetworkCredential("fileprocessing@yandex.ru", "fpf_smtp");
            Smtp.Send(Message);
        }
    }




}
